﻿using System;
using System.Windows.Forms;
using SharePointUtilitiesForDevelopers.Repository;
using SharePointUtilitiesForDevelopers.Service;

namespace SharePointUtilitiesForDevelopers.Client.Forms
{
    /// <summary>
    /// Shows the open site dialog.
    /// </summary>
    public partial class OpenSiteForm : Form
    {
        #region Fields

        private readonly ISharePointWebRepository _webRepository;

        #endregion Fields

        #region Constructors
        
        /// <summary>
        /// Initializes a new instance of the <see cref="OpenSiteForm"/> class.
        /// </summary>
        /// <param name="webRepository">The web repository.</param>
        public OpenSiteForm(ISharePointWebRepository webRepository)
        {
            InitializeComponent();

            // Get the dependencies
            _webRepository = webRepository;
        }

        #endregion Constructors

        #region Properties

        /// <summary>
        /// Gets or sets the site URL.
        /// </summary>
        /// <value>The site URL.</value>
        public string SiteUrl { get; set; }

        /// <summary>
        /// Gets or sets the web.
        /// </summary>
        /// <value>The web.</value>
        public SharePointWeb Web { get; set; }

        /// <summary>
        /// Gets or sets the web load options.
        /// </summary>
        /// <value>The web load options.</value>
        public SharePointWebLoadOptions WebLoadOptions { get; set; }

        #endregion Properties

        #region Helper Methods

        /// <summary>
        /// Gets the name of the current user.
        /// </summary>
        /// <returns></returns>
        private static string GetCurrentUserName()
        {
            string userName = string.Format(
                "{0}{1}{2}",
                Environment.UserDomainName,
                string.IsNullOrEmpty(Environment.UserDomainName) ? string.Empty : "\\",
                Environment.UserName);
            return userName;
        }

        /// <summary>
        /// Attempts to open the site.
        /// </summary>
        /// <param name="siteUrl">The site URL.</param>
        /// <returns></returns>
        private bool OpenSite(string siteUrl)
        {
            try
            {
                // Set the credentials
                if(integratedAuthRadioButton.Checked)
                {
                    SharePointServiceCredentialCache.SetCredential(siteUrl);
                }
                if(userNamePasswordRadioButton.Checked)
                {
                    SharePointServiceCredentialCache.SetCredential(siteUrl, userNameTextBox.Text, passwordTextBox.Text);
                }

                // Get the web
                Web = _webRepository.GetWeb(siteUrl, WebLoadOptions);
                return true;
            }
            catch(Exception ex)
            {
                // Failed to connect
                MessageBox.Show(
                    this,
                    "Failed to open site. " + Environment.NewLine + ex.Message,
                    "Open Site",
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Exclamation);
                
                return false;
            }
        }

        /// <summary>
        /// Sets the user name authentication mode controls.
        /// </summary>
        private void SetAuthenticationMode()
        {
            userNameTextBox.Enabled = userNamePasswordRadioButton.Checked;
            passwordTextBox.Enabled = userNamePasswordRadioButton.Checked;
            rememberPasswordCheckBox.Enabled = userNamePasswordRadioButton.Checked;
            if(userNameTextBox.Enabled && userNameTextBox.Text == string.Empty)
            {
                userNameTextBox.Text = GetCurrentUserName();
            }
        }

        /// <summary>
        /// Validates the form.
        /// </summary>
        private bool ValidateForm()
        {
            bool isValid = true;

            errorProvider.Clear();

            // Site url
            if (siteUrlComboBox.Text == string.Empty)
            {
                errorProvider.SetError(siteUrlComboBox, Properties.Resources.ValidationSiteUrlRequired);
                isValid = false;
            }
            else
            {
                // Site url format
                Uri uri;
                if(!Uri.TryCreate(siteUrlComboBox.Text, UriKind.Absolute, out uri))
                {
                    errorProvider.SetError(siteUrlComboBox, Properties.Resources.ValidationSiteUrlFormat);
                    isValid = false;
                }
            }
            
            // If user name / password, validate
            if (userNamePasswordRadioButton.Checked)
            {
                // User Name
                if (userNameTextBox.Text == string.Empty)
                {
                    errorProvider.SetError(userNameTextBox, Properties.Resources.ValidationUserNameRequired);
                    isValid = false;
                }

                // Password
                if (passwordTextBox.Text == string.Empty)
                {
                    errorProvider.SetError(passwordTextBox, Properties.Resources.ValidationPasswordRequired);
                    isValid = false;
                }
            }

            // Return result
            return isValid;
        }

        #endregion Helper Methods

        #region Event Handlers

        /// <summary>
        /// Handles the Load event of the OpenSiteForm control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void OpenSiteForm_Load(object sender, EventArgs e)
        {
            // Set the authentication mode
            SetAuthenticationMode();
        }

        /// <summary>
        /// Handles the Shown event of the OpenSiteForm control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void OpenSiteForm_Shown(object sender, EventArgs e)
        {
            // Set the url
            siteUrlComboBox.Text = string.IsNullOrEmpty(SiteUrl) ? "http://" : SiteUrl;
            siteUrlComboBox.SelectAll();
            
        }

        /// <summary>
        /// Handles the CheckedChanged event of the integratedAuthRadioButton control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void integratedAuthRadioButton_CheckedChanged(object sender, EventArgs e)
        {
            SetAuthenticationMode();
        }

        /// <summary>
        /// Handles the CheckedChanged event of the basicAuthRadioButton control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void basicAuthRadioButton_CheckedChanged(object sender, EventArgs e)
        {
            SetAuthenticationMode();
        }

        /// <summary>
        /// Handles the Click event of the okButton control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void okButton_Click(object sender, EventArgs e)
        {
            try
            {
                // Show wait
                Enabled = false;
                Cursor = Cursors.WaitCursor;

                // Validate
                if(!ValidateForm())
                {
                    return;
                }

                // Try to connect to the site
                var siteUrl = siteUrlComboBox.Text;
                if (!OpenSite(siteUrl))
                {
                    return;
                }

                // Remember the site url
                var siteUri = new Uri(siteUrl); // create uri for consistency
                if (!siteUrlComboBox.Items.Contains(siteUri.ToString()))
                {
                    siteUrlComboBox.Items.Add(siteUri.ToString()); 
                }

                // Save the site url
                SiteUrl = siteUri.ToString();

                // Clear password on close
                if (!rememberPasswordCheckBox.Checked)
                {
                    passwordTextBox.Clear();
                }

                // Hide form
                DialogResult = DialogResult.OK;
                Hide();
            }
            finally
            {
                Enabled = true;
                Cursor = Cursors.Default;
            }
        }

        /// <summary>
        /// Handles the Click event of the cancelButton control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void cancelButton_Click(object sender, EventArgs e)
        {
            // Hide form
            DialogResult = DialogResult.Cancel;
            Hide();
        }

        #endregion Event Handlers

    }
}